package com.zhiyin.seal.task;

import com.google.common.collect.Lists;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.zhiyin.seal.entity.bo.*;
import com.zhiyin.seal.service.ApplyService;
import com.zhiyin.seal.service.StampService;
import com.zhiyin.seal.util.DateUtil;
import com.zhiyin.seal.util.HeaderFooter;
import com.zhiyin.seal.util.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

@Component
public class PdfTask {

    @Autowired
    ApplyService applyService;

    @Autowired
    StampService stampService;

    @Value("${myconfig.image-path}")
    private String imagePath;

    @Value("${myconfig.file-path}")
    private String filePath;

    @Value("${myconfig.domain}")
    private String host;

    @Value("${myconfig.downloadpdf}")
    private String downloadPdf;

    /**
     * 自动关闭单据
     */
    @Scheduled(fixedDelay = 1000 * 2)
    public void autoCloseApply(){
        ApplyBo applyBo = applyService.getExpireApplySingle();
        if(applyBo != null){
            // 关闭单据
            applyService.closeApply(applyBo.getId());
        }
    }

    /**
     * 申请单pdf任务
     */
    @Scheduled(fixedDelay = 1000 * 2)
    public void applyPdfJob(){
        // 获取待处理的申请单的pdf任务
        List<PdfTaskBo> pdfTaskBoList = applyService.getPendingPdfTaskList();
        if(pdfTaskBoList.size() == 0){
            return;
        }
        for (PdfTaskBo pdfTaskBo : pdfTaskBoList) {
            // 任务id
            Long taskId = pdfTaskBo.getId();
            // 申请单id
            Long applyId = pdfTaskBo.getApplyId();
            // 类型
            Integer type = pdfTaskBo.getType();
            // 获取上传的图片
            List<ApplyPhotoBo> applyPhotoBoList = applyService.getApplyImageList(pdfTaskBo.getApplyId(),pdfTaskBo.getType());
            // 填充图片路径集合
            List<String> imagePathList = Lists.newArrayList();
            if(applyPhotoBoList.size() > 0){
                for (int i = 0; i < applyPhotoBoList.size(); i++) {
                    ApplyPhotoBo applyPhotoBo = applyPhotoBoList.get(i);
                    String imageUrl = applyPhotoBo.getImageUrl();
                    String[] imageNames = imageUrl.split("=");
                    if(imageNames.length == 2){
                        String imageName = imageNames[1];
                        String filePath = imagePath + "/" + imageName;
                        imagePathList.add(filePath);
                    }
                }
            }
            // 生成pdf文件
            generatePdf(taskId,applyId,type,imagePathList);
        }
    }

    /**
     * 生成pdf文件
     * @param taskId 任务id
     * @param applyId 申请单id
     * @param type 类型 1:申请pdf,2:盖章pdf
     * @param imagePathList 图片路径集合
     */
    protected void generatePdf(Long taskId,Long applyId,Integer type,List<String> imagePathList){
        // 判断如果单据id为0
        if(applyId == 0){
            // 直接更新处理状态
            applyService.updatePdfTaskStatus(taskId);
            return;
        }
        // 创建pdf文档
        Document document = new Document(PageSize.A4);
        ApplyDetailBo applyDetailBo = applyService.getApplyDetailInfo(applyId);
        // 生成文件名
        String fileName = UUIDUtil.getUUIDString(false) + ".pdf";
        // pdf文件路径=根目录+公司id+文件分类+文件名称
        String fileType = type == 1 ? "apply" : "stamp";
        // 目录不存在则创建
        File pdfFile = new File(filePath + "/" + applyDetailBo.getCompanyId() + "/" + fileType );
        if(!pdfFile.exists()){
            pdfFile.mkdirs();// 创建多层目录
        }
        // pdf文件路径
        String pdfFilePath = filePath + "/" + applyDetailBo.getCompanyId() + "/" + fileType + "/" + fileName;
        // pdf文件下载地址
        String pdfUrl = host + downloadPdf + "?fileName=" + fileName + "&companyId=" + applyDetailBo.getCompanyId() + "&type=" + type;
        try {
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath));
            // 设置水印
            HeaderFooter header = new HeaderFooter(null,applyDetailBo.getCompanyInfo().getName());
            writer.setPageEvent(header);
            // 打开文档
            document.open();
            // 设置字体
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            // 写入申请事由
            Font f = new Font(bfChinese, 22, Font.BOLD);
            f.setFamily("微软雅黑");
            Paragraph pApplyTitle = new Paragraph(applyDetailBo.getReason(),f);
            pApplyTitle.setAlignment(Paragraph.ALIGN_CENTER);
            pApplyTitle.setSpacingAfter(20);
            document.add(pApplyTitle);
            // 插入单据表格信息
            f = new Font(bfChinese, 14, Font.BOLD);
            f.setFamily("微软雅黑");
            PdfPTable table =  new PdfPTable(4);
            int headerWidths[] = {20, 20, 20, 40};
            table.setWidths(headerWidths);
            table.setWidthPercentage(100);
            table.getDefaultCell().setPadding(3);
            table.getDefaultCell().setBorderWidth(2);
            table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
            PdfPCell cell1 = new PdfPCell(new Phrase(("申请人名称"), f));
            table.addCell(cell1);
            PdfPCell cell2 = new PdfPCell(new Phrase(("印章名称"), f));
            table.addCell(cell2);
            PdfPCell cell3 = new PdfPCell(new Phrase(("申请次数"), f));
            table.addCell(cell3);
            PdfPCell cell4 = new PdfPCell(new Phrase(("申请时间"), f));
            table.addCell(cell4);
            f = new Font(bfChinese, 11, Font.NORMAL);
            f.setFamily("微软雅黑");
            PdfPCell cellApplyUser = new PdfPCell(new Paragraph(applyDetailBo.getApplyUserInfo().getNickName(),f));
            table.addCell(cellApplyUser);
            PdfPCell cellSeal = new PdfPCell(new Paragraph(applyDetailBo.getSealInfo().getName(),f));
            table.addCell(cellSeal);
            PdfPCell cellApplyCount = new PdfPCell(new Paragraph(applyDetailBo.getApplyCount().toString(),f));
            table.addCell(cellApplyCount);
            PdfPCell cellApplyTime = new PdfPCell(new Paragraph(DateUtil.COMMON_DATE_FORMATE.format(applyDetailBo.getCreateTime()),f));
            table.addCell(cellApplyTime);
            document.add(table);
            // 判断是否为盖章文件
            if(type == 2){
                // 插入审批表格信息
                f = new Font(bfChinese, 14, Font.BOLD);
                f.setFamily("微软雅黑");
                Paragraph pApprovalTitle = new Paragraph("审批人列表",f);
                pApprovalTitle.setAlignment(Paragraph.ALIGN_CENTER);
                pApprovalTitle.setSpacingAfter(20);
                document.add(pApprovalTitle);

                PdfPTable tApproval =  new PdfPTable(2);
                int approvalHeaderWidths[] = {50, 50};
                tApproval.setWidths(approvalHeaderWidths);
                tApproval.setWidthPercentage(100);
                tApproval.getDefaultCell().setPadding(3);
                tApproval.getDefaultCell().setBorderWidth(2);
                tApproval.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
                PdfPCell cApprovalName = new PdfPCell(new Phrase(("审批人名称"), f));
                tApproval.addCell(cApprovalName);
                PdfPCell ccName = new PdfPCell(new Phrase(("抄送人名称"), f));
                tApproval.addCell(ccName);
                String approvalNames = "无审批人";
                List<MyApprovalBo> myApprovalBoList = applyDetailBo.getApprovalList();
                if(myApprovalBoList.size() > 0){
                    List<String> approvalNameList = Lists.newArrayList();
                    myApprovalBoList.forEach(approvalBo->{
                        if(approvalBo.getHandleTime() != null){
                            approvalNameList.add(approvalBo.getUserInfo().getNickName());
                        }
                    });
                    if(approvalNameList.size() > 0){
                        approvalNames = StringUtils.join(approvalNameList,",");
                    }
                }
                String ccNames = "无抄送人";
                List<MyCCBo> myCCBoList = applyDetailBo.getCcList();
                if(myCCBoList.size() > 0){
                    List<String> ccNameList = Lists.newArrayList();
                    myCCBoList.forEach(ccBo->{
                        ccNameList.add(ccBo.getUserInfo().getNickName());
                    });
                    if(ccNameList.size() > 0){
                        ccNames = StringUtils.join(ccNameList,",");
                    }
                }
                f = new Font(bfChinese, 11, Font.NORMAL);
                f.setFamily("微软雅黑");
                cApprovalName = new PdfPCell(new Phrase((approvalNames), f));
                tApproval.addCell(cApprovalName);
                ccName = new PdfPCell(new Phrase((ccNames), f));
                tApproval.addCell(ccName);
                document.add(tApproval);

                // 插入盖章记录表格信息
                f = new Font(bfChinese, 14, Font.BOLD);
                f.setFamily("微软雅黑");
                Paragraph pStampTitle = new Paragraph("盖章记录",f);
                pStampTitle.setAlignment(Paragraph.ALIGN_CENTER);
                pStampTitle.setSpacingAfter(20);
                document.add(pStampTitle);
                PdfPTable tStampRecord =  new PdfPTable(6);
                int stampHeaderWidths[] = {10,15,10,15,30,20};
                tStampRecord.setWidths(stampHeaderWidths);
                tStampRecord.setWidthPercentage(100);
                tStampRecord.getDefaultCell().setPadding(3);
                tStampRecord.getDefaultCell().setBorderWidth(2);
                tStampRecord.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
                PdfPCell cStampName = new PdfPCell(new Phrase(("用印人"), f));
                tStampRecord.addCell(cStampName);
                PdfPCell cSealName = new PdfPCell(new Phrase(("印章名称"), f));
                tStampRecord.addCell(cSealName);
                PdfPCell cStampCount = new PdfPCell(new Phrase(("盖章次数"), f));
                tStampRecord.addCell(cStampCount);
                PdfPCell cStampTime = new PdfPCell(new Phrase(("用印时间"), f));
                tStampRecord.addCell(cStampTime);
                PdfPCell cStampAddress = new PdfPCell(new Phrase(("用印地点"), f));
                tStampRecord.addCell(cStampAddress);
                PdfPCell cFace = new PdfPCell(new Phrase(("用印人脸"), f));
                tStampRecord.addCell(cFace);

                f = new Font(bfChinese, 11, Font.NORMAL);
                f.setFamily("微软雅黑");
                // 查询盖章记录
                List<StampRecordBo> stampRecordBoList = stampService.getRecordByApplyId(applyId);
                for(int i =0;i<stampRecordBoList.size();i++){
                    StampRecordBo stampRecordBo = stampRecordBoList.get(i);
                    String stampUserName = stampRecordBo.getStampUser().getNickName();
                    String sealName = stampRecordBo.getSealInfo().getName();
                    String stampCount = stampRecordBo.getStampCount().toString();
                    String stampTime = DateUtil.COMMON_DATE_FORMATE.format(stampRecordBo.getCreateTime());
                    String address = stampRecordBo.getAddress();
                    cStampName = new PdfPCell(new Phrase((stampUserName), f));
                    tStampRecord.addCell(cStampName);
                    cSealName = new PdfPCell(new Phrase((sealName), f));
                    tStampRecord.addCell(cSealName);
                    cStampCount = new PdfPCell(new Phrase((stampCount), f));
                    tStampRecord.addCell(cStampCount);
                    cStampTime = new PdfPCell(new Phrase((stampTime), f));
                    tStampRecord.addCell(cStampTime);
                    cStampAddress = new PdfPCell(new Phrase((address), f));
                    tStampRecord.addCell(cStampAddress);
                    // 头像
                    if(stampRecordBo.getFacePhotoUrl() != null){
                        String facePhotoUrl = stampRecordBo.getFacePhotoUrl();
                        String[] faceImageNames = facePhotoUrl.split("=");
                        if(faceImageNames.length == 2){
                            String faceName = faceImageNames[1];
                            String faceFilePath = imagePath + "/" + faceName;
                            Image faceImage = Image.getInstance(faceFilePath);
                            faceImage.setAlignment(Image.MIDDLE);
                            faceImage.scaleAbsolute(80,80);
                            cFace = new PdfPCell();
                            cFace.setFixedHeight(100);
                            cFace.setHorizontalAlignment(Element.ALIGN_CENTER);
                            cFace.setVerticalAlignment(Element.ALIGN_MIDDLE);
                            cFace.setPhrase(new Paragraph(new Chunk(faceImage, 0, -40)));
                            tStampRecord.addCell(cFace);
                        } else {
                            cFace = new PdfPCell(new Phrase(("无"), f));
                            tStampRecord.addCell(cFace);
                        }
                    } else {
                        cFace = new PdfPCell(new Phrase(("无"), f));
                        tStampRecord.addCell(cFace);
                    }
                }
                document.add(tStampRecord);
            }
            // 插入文件二维码
            BarcodeQRCode barcodeQRCode = new BarcodeQRCode(pdfUrl, 100, 100, null);
            Image codeQrImage = barcodeQRCode.getImage();
            codeQrImage.setAlignment(Image.ALIGN_CENTER);
            document.add(codeQrImage);
            f = new Font(bfChinese,11, Font.NORMAL);
            f.setFamily("微软雅黑");
            Paragraph pQRCode = new Paragraph("微信扫描查看电子文档",f);
            pQRCode.setAlignment(Paragraph.ALIGN_CENTER);
            document.add(pQRCode);
            // 插入图片
            for(int i = 0;i<imagePathList.size();i++){
                //创建页
                document.newPage();
                String imgPath = imagePathList.get(i);
                Image image = Image.getInstance(imgPath);
                float imageHeight=image.getHeight();
                float imageWidth=image.getWidth();
                int percent=getPercent(imageHeight, imageWidth);
                image.setAlignment(Image.MIDDLE);
                image.scalePercent(percent);
                document.add(image);
            }
        } catch (Exception ex){
            System.out.println("生成pdf文件失败：" + ex.getMessage());
        } finally {
            try {
                if(document.isOpen()){
                    document.close();
                }
            } catch (Exception ex) {
                System.out.println("关闭文档失败：" + ex.getMessage());
            } finally{
                // 更新pdf任务状态
                applyService.updatePdfTaskStatus(taskId);
                // 更新单据pdf文档
                if(type == 1){
                    applyService.updateApplyPdfUrl(applyId,pdfUrl);
                } else {
                    applyService.updateStampPdfUrl(applyId,pdfUrl);
                }
            }
        }
    }

    /**
     * 计算缩小比例，宽度和高度的缩小比例取最小值
     * @param h
     * @param w
     * @return
     */
    protected int getPercent(float h,float w)
    {
        // 按照宽度计算缩小比例
        float p1=0.0f;
        p1=550/w*100;
        // 按照高度计算缩小比例
        float p2=0.0f;
        p2=750/h*100;
        if(p1 >= p2){
            return Math.round(p2);
        } else {
            return Math.round(p1);
        }
    }
}
